package org.elastic.compreplatform.admin.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xiaoleilu.hutool.date.DateUtil;

/**
 * ClassName: HttpClientUtil 
 * @Description: 
 * @author JornTang
 * @email 957707261@qq.com
 * @date 2017年8月17日
 */
public class HttpClientUtil {
	private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
	private static int HTTP_TIMEOUT=1000*60*5;
	/** 超时时间 */
    private static int timeout = 10000;
	/**
	 * @Description: 获取httpClient实例的方法
	 * @return   
	 * @return HttpClient  
	 * @throws
	 * @author JornTang
	 * @date 2018年2月11日
	 */
    public static HttpClient getHttpClient()
    {
    	HttpClient httpClient = new HttpClient(new SimpleHttpConnectionManager(true));
        httpClient.getParams().setSoTimeout(timeout);
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
        httpClient.getParams().setBooleanParameter("http.protocol.expect-continue", false);
        return httpClient;
    }
    /**
     * @Description: 根据代理IP和端口号 获取httpClient实例的方法
     * @param host
     * @param port
     * @return   
     * @return HttpClient  
     * @throws
     * @author JornTang
     * @date 2018年2月11日
     */
    public static HttpClient getHttpClient(String host, Integer port)
    {
    	HttpClient httpClient = new HttpClient(new SimpleHttpConnectionManager(true));
        httpClient.getParams().setSoTimeout(timeout);
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
        httpClient.getParams().setBooleanParameter("http.protocol.expect-continue", false);
        httpClient.getHostConfiguration().setProxy(host, port);
        return httpClient;
    }
	public static String post(String reqURL,Map<String, Object> params) throws Exception{
		HttpPost httpPost = new HttpPost(reqURL);
		CloseableHttpClient httpClient = HttpClients.createDefault();
		try {
			// init post
			if (params != null && !params.isEmpty()) {
				List<NameValuePair> formParams = new ArrayList<NameValuePair>();
				for (Map.Entry<String, Object> entry : params.entrySet()) {
					Object v= entry.getValue();
					String value="";
					if(v instanceof Date && v!= null){
						value= DateUtil.format((Date)v, "yyyy-MM-dd HH:mm:ss");
					}else{
						if(v!= null){
							value= v.toString();
						}
					}
					formParams.add(new BasicNameValuePair(entry.getKey(), value));
				}
				httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
			}
			//http设置超时
			RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(HTTP_TIMEOUT)
                    .setSocketTimeout(HTTP_TIMEOUT)
                    .setConnectTimeout(HTTP_TIMEOUT)
                    .build();

			httpPost.setConfig(requestConfig);
			httpPost.setHeader("Content-Type", "application/json");
			// do post
			HttpResponse response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			if (null != entity) {
				return EntityUtils.toString(entity);
			}
			return null;
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			httpPost.releaseConnection();
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * @Description: 
	 * @param reqURL
	 * @param date
	 * @param params
	 * @return
	 * @throws Exception   
	 * @return JsonNode  
	 * @throws
	 * @author JornTang
	 * @date 2017年12月27日
	 */
	public static JsonNode postRequest(String reqURL, byte[] date,Map<String, Object> params) throws Exception {
		byte[] responseBytes = null;
		HttpPost httpPost = new HttpPost(reqURL);
		CloseableHttpClient httpClient = HttpClients.createDefault();
		try {
			// init post
			if (params != null && !params.isEmpty()) {
				List<NameValuePair> formParams = new ArrayList<NameValuePair>();
				for (Map.Entry<String, Object> entry : params.entrySet()) {
					Object v= entry.getValue();
					String value="";
					if(v instanceof Date && v!= null){
						value= DateUtil.format((Date)v, "yyyy-MM-dd HH:mm:ss");
					}else{
						if(v!= null){
							value= v.toString();
						}
					}
					//if(entry.getKey().equalsIgnoreCase("id"))continue;
					formParams.add(new BasicNameValuePair(entry.getKey(), value));
				}
				httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
			}

			//http设置超时
			RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(HTTP_TIMEOUT)
                    .setSocketTimeout(HTTP_TIMEOUT)
                    .setConnectTimeout(HTTP_TIMEOUT)
                    .build();

			httpPost.setConfig(requestConfig);

			// data
			if (date != null) {
				httpPost.setEntity(new ByteArrayEntity(date, ContentType.DEFAULT_BINARY));
			}
			// do post
			HttpResponse response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			if (null != entity) {
				responseBytes = EntityUtils.toByteArray(entity);
				EntityUtils.consume(entity);
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		} finally {
			httpPost.releaseConnection();
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		//转换成JSON对象
		ObjectMapper objectMapper = new ObjectMapper();
		return objectMapper.readTree(responseBytes);
	}
	/**
	 * @Description: 发送get请求
	 * @param reqURL
	 * @return
	 * @throws ESSearchException   
	 * @return String  
	 * @author JornTang
	 * @date 2017年12月27日
	 */
    public static URLConnection get(String reqURL) throws Exception {  
        BufferedReader in = null;  
        try {  
            URL realUrl = new URL(reqURL);  
            // 打开和URL之间的连接  
            URLConnection connection = realUrl.openConnection();  
            // 设置通用的请求属性  
            connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            connection.setRequestProperty("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");  
            connection.setRequestProperty("connection", "keep-alive");  
            connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36");  
            connection.setConnectTimeout(20000);  
            connection.setReadTimeout(20000);  
            return connection;
        } catch (Exception e) {  
           throw new Exception("ES索引查询异常",e);
        }  finally {  
            try {  
                if (in != null) {  
                    in.close();  
                }  
            } catch (Exception e2) {  
                e2.printStackTrace();  
            }  
        }  
    } 
	/**
	 * read bytes from http request
	 * @param request
	 * @return
	 * @throws IOException 
	 */
	public static final byte[] readBytes(HttpServletRequest request) throws IOException {
		request.setCharacterEncoding("UTF-8");
        int contentLen = request.getContentLength();
		InputStream is = request.getInputStream();
		if (contentLen > 0) {
			int readLen = 0;
			int readLengthThisTime = 0;
			byte[] message = new byte[contentLen];
			try {
				while (readLen != contentLen) {
					readLengthThisTime = is.read(message, readLen, contentLen - readLen);
					if (readLengthThisTime == -1) {
						break;
					}
					readLen += readLengthThisTime;
				}
				return message;
			} catch (IOException e) {
				e.printStackTrace();
				throw e;
			}
		}
		return new byte[] {};
	}

}
